package com.gin.kotlin.no_gay_alliance.fragment.main.setting

import android.content.DialogInterface
import android.content.Intent
import android.os.Message
import android.util.Base64
import android.util.Log
import android.view.View
import android.widget.EditText
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper
import com.gin.kotlin.no_gay_alliance.R
import com.gin.kotlin.no_gay_alliance.activity.LoginActivity
import com.gin.kotlin.no_gay_alliance.activity.LoginActivity.Companion.KEY_COOKIE
import com.gin.kotlin.no_gay_alliance.adapter.NgaAccountAdapter
import com.gin.kotlin.no_gay_alliance.base.AbstractBindingFragment
import com.gin.kotlin.no_gay_alliance.base.AlertDialogUtils
import com.gin.kotlin.no_gay_alliance.base.ClipboardUtils
import com.gin.kotlin.no_gay_alliance.database.entity.NgaAccount
import com.gin.kotlin.no_gay_alliance.databinding.FragmentMainSettingAccountManagerBinding
import com.gin.kotlin.no_gay_alliance.enums.HandlerMessageWhat
import com.gin.kotlin.no_gay_alliance.manager.AccountManager
import com.gin.nga.cookie.NgaCookie

/**
 * 账号管理
 */
class AccountManagerFragment : AbstractBindingFragment<FragmentMainSettingAccountManagerBinding>(), View.OnClickListener, ActivityResultCallback<ActivityResult> {
    private lateinit var launcher: ActivityResultLauncher<Intent>
    private lateinit var adapter: NgaAccountAdapter
    private lateinit var manager: AccountManager

    override fun onCreateView() {
        this.manager = AccountManager.getInstance()

        val b = this.b ?: return

        b.btLoginWithPwd.setOnClickListener(this)
        b.btExport.setOnClickListener(this)
        b.btImport.setOnClickListener(this)

        this.adapter = NgaAccountAdapter(requireContext(), handler!!)
        b.recyclerView.adapter = adapter

        this.launcher = registerLauncher(this)
    }

    override fun onResume() {
        super.onResume()
        list()
    }

    /**
     * 处理消息
     */
    override fun handleMessage(msg: Message): Boolean {
        if (msg.what == HandlerMessageWhat.ACCOUNT_LIST_REFRESH.ordinal) {
            list()
            return true
        }
        return super.handleMessage(msg)
    }

    /**
     * 查询列表并装载
     */
    private fun list() {
        adapter.replaceData(this.manager.list())
    }

    override fun onClick(v: View?) {
        val b = this.b ?: return
        when (v) {
            b.btLoginWithPwd -> this.launcher.launch(Intent(context, LoginActivity::class.java))
            b.btExport -> exportCookie()
            b.btImport -> importCookie()
        }
    }

    /**
     * Called when result is available
     */
    override fun onActivityResult(result: ActivityResult) {
        val cookie = result.data?.getStringExtra(KEY_COOKIE) ?:return
        val account = NgaAccount(NgaCookie(cookie))
        AccountManager.getInstance().add(account)
        toast(getString(R.string.toast_message_account_added, account.username))
        list()
    }

    /**
     * 导出cookie, 转换为导出字符串后使用 ObjectMapper 序列化，再Base64编码
     */
    private fun exportCookie() {
        val data = this.manager.list().map { it.toExportString() }
        val text = ObjectMapper().writeValueAsString(data)
        ClipboardUtils.setText(Base64.encodeToString(text.toByteArray(), Base64.DEFAULT))
        Log.i(TAG, "账号信息已导出")

        //弹窗提示
        AlertDialogUtils.builder(requireContext(), getString(R.string.dialog_title_account_exported), getString(R.string.dialog_content_account_exported)).show()
    }

    private fun importCookie() {
        //弹窗输入
        val editText = EditText(requireContext())
        editText.hint = getString(R.string.edit_text_hint_please_enter_cookie_string)

        AlertDialogUtils.builder(requireContext(), getString(R.string.alert_dialog_title_import_account), contentView = editText, listener = { _, which ->
            if (which == DialogInterface.BUTTON_POSITIVE) {
                // 导入信息
                val text = String(Base64.decode(editText.text.toString(), Base64.DEFAULT))
                Log.i(TAG, "导入账号信息: $text")
                val list = ObjectMapper().readValue(text, object : TypeReference<List<String>>() {})
                val accounts = list.map { NgaAccount().fromExportString(it) }
                AccountManager.getInstance().add(accounts)
                handler?.toast(getString(R.string.toast_message_account_imported))
                list()
            }
        }).show()

        ui { editText.requestFocus() }
    }
}